home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / tproject.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  24.9 KB  |  919 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW IDE                       |
  4. // |  File:        TPROJECT.CPP                         |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Tproject class implementation        |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_stdio
  16. #define uses_string
  17.  
  18. #define uses_app
  19. #define uses_check
  20. #define uses_desk
  21. #define uses_ht
  22. #define uses_input
  23. #define uses_stddlg
  24. #define uses_system
  25. #define uses_table
  26. #define uses_txt
  27.  
  28. #include "PVUSES.H"
  29. #include "W.H"
  30. #include "COMPILE.H"
  31.  
  32. #define _DECLARE_TPROJECT_H
  33.   #include "TPROJECT.H"
  34. #undef  _DECLARE_TPROJECT_H
  35.  
  36.  
  37. /*
  38. STATIC DATA
  39. */
  40.   static char prj_signature[] = "\r\nPower View IDE project file.\r\n\032";
  41.  
  42.  
  43. static void free_project_entry( void *p )
  44. {
  45.   DELETE( ((Tproject_entry *)p)->depends );
  46.   FREE( ( (Tproject_entry *) p)->command_line );
  47.   FREE( ( (Tproject_entry *) p)->compiler );
  48. }
  49.  
  50. static boolean break_make( void )
  51. {
  52.   Tevent ev;
  53.   for(;;)
  54.   {
  55.     get_event( ev );
  56.     if( ev.code==evNOTHING ) return 0;
  57.     if( ev.code!=evCOMMAND )
  58.     {
  59.       if( ev.code==evKEY_DOWN && ev.SCAN_CODE==scESC )
  60.       {
  61.         while( ev.code!=evKEY_UP || ev.SCAN_CODE!=scESC ) get_event( ev );
  62.         return 1;
  63.       }
  64.       continue;
  65.     }
  66.     modal_item->handle_event( ev );
  67.   }
  68. }
  69.  
  70.  
  71. /*
  72. public
  73. */
  74.   Tproject::Tproject( char *_filename, int _xl, int _yl, boolean show_error ):
  75.     Thide_on_close( _xl, _yl )
  76.   {
  77.     char tmp_signature[ sizeof( prj_signature ) ];
  78.     Tproject_entry pe;
  79.     char cmd[128];
  80.     char comp[21];
  81.     char buf[_MAX_PATH];
  82.     FILE *f;
  83.     uint i, j;
  84.     boolean success;
  85.  
  86.     scroll_ahead = 1;
  87.     memset( &prj_compiler_options, 0, sizeof(prj_compiler_options) );
  88.     memset( &prj_linker_options,   0, sizeof(prj_linker_options  ) );
  89.     data_size = TPROJECT_ENTRY_SIZE;
  90.     lb_item_killer = free_project_entry;
  91.     *filename = 0;
  92.     if( *_filename == 0 ) return;
  93.     fexpand( strcpy( filename, _filename ) );
  94.     f = fopen( filename, "rb" );
  95.     if( f == NULL )
  96.     {
  97.       if( show_error )
  98.       {
  99.         _terror();
  100.         ok( "Unable to open project file \"%s\".", filename );
  101.         goto not_valid;
  102.       }
  103.       return;
  104.     }
  105.     memset( tmp_signature, 0, sizeof( tmp_signature ) );
  106.     fread( tmp_signature, sizeof( tmp_signature ), 1, f );
  107.     if( memcmp( tmp_signature, prj_signature, sizeof( tmp_signature ) ) )
  108.     {
  109.       _terror();
  110.       ok( "\"%s\" is not a Power View IDE project file.", filename );
  111.       set_state( isVALID, 0 );
  112.       fclose( f );
  113.       return;
  114.     }
  115.     success = ( fread( &i, sizeof( i ), 1, f ) == 1 );
  116.     i++;
  117.     while( success && --i )
  118.     {
  119.       success = (
  120.         ( fread( &pe,  sizeof( pe ),   1, f ) == 1 ) &&
  121.         ( fread( cmd,  sizeof( cmd ),  1, f ) == 1 ) &&
  122.         ( fread( comp, sizeof( comp ), 1, f ) == 1 ) &&
  123.         ( fread( &j,   sizeof( uint ), 1, f ) == 1 )
  124.       );
  125.       if( !success ) break;
  126.       pe.depends = NEW( Tlb_list );
  127.       pe.command_line = STRDUP( cmd );
  128.       pe.compiler = STRDUP( comp );
  129.       j++;
  130.       while( success && --j )
  131.         if( success = ( fread( buf, sizeof( buf ), 1, f ) == 1 ) )
  132.           pe.depends->add( buf );
  133.       if( success ) add( &pe );
  134.     }
  135.     success = success && fread( &prj_compiler_options, sizeof(prj_compiler_options), 1, f )==1
  136.                       && fread( &prj_linker_options,   sizeof(prj_linker_options  ), 1, f )==1;
  137.     Tlb_list::top();
  138.     fclose( f );
  139.     if( !success || ferror( f ) )
  140.     {
  141.       _terror();
  142.       ok( "Error reading project file \"%s\".", filename );
  143.     not_valid:
  144.       set_state( isVALID, 0 );
  145.     }
  146.   }
  147.  
  148.   void Tproject::fetch( char *buffer, uint row, uint column, uint width )
  149.   {
  150.     Tproject_entry *pe;
  151.  
  152.     if( row == vcurrent ) text_attr = selected_attr;
  153.     pe = (Tproject_entry *) getptr( row );
  154.     switch( column )
  155.     {
  156.       case 0:
  157.         strcpy( buffer, pe->filename );
  158.         min_path( buffer );
  159.         short_path( buffer, width );
  160.         break;
  161.       case 1:
  162.         target_file( buffer, pe->target );
  163.         min_path( buffer );
  164.         short_path( buffer, width );
  165.         break;
  166.     }
  167.   }
  168.  
  169.   void Tproject::set_title( void )
  170.   {
  171.     if( *filename )
  172.       Thide_on_close::set_title( filename );
  173.     else
  174.       Thide_on_close::set_title( "[untitled]" );
  175.   }
  176.  
  177.   boolean Tproject::save( void )
  178.   {
  179.     if( *filename == 0 ) return save_as();
  180.     return save_project();
  181.   }
  182.  
  183.   boolean Tproject::save_as( void )
  184.   {
  185.     static char dir_svd[_MAX_PATH] = "";
  186.     static uint filt_svd = 0;
  187.     _get_file_svd( dir_svd, filt_svd );
  188.     _new_file();
  189.     _filters( "Project files (*.wpj)" );
  190.     if( get_file( "Save project as", filename ) != cmOK ) return 0;
  191.     return save_project();
  192.   }
  193.  
  194.   boolean Tproject::save_project( void )
  195.   {
  196.     FILE *f;
  197.     uint i, j;
  198.     Tproject_entry pe;
  199.     char cmd[128], comp[21];
  200.     char buf[_MAX_PATH];
  201.     boolean result;
  202.  
  203.     redraw();
  204.     f = fopen( filename, "wb" );
  205.     if( f == NULL ) return 0;
  206.     result = ( fwrite( prj_signature, sizeof( prj_signature ), 1, f ) == 1 ) &&
  207.              ( fwrite( &vcount,       sizeof( vcount ),        1, f ) == 1 );
  208.     for( i = 0; result && ( i < vcount ); i++ )
  209.     {
  210.       get( i, &pe );
  211.       pe.options &= ~peBUILD;
  212.       strcpy( cmd, pe.command_line );
  213.       strcpy( comp, pe.compiler );
  214.       if( ( fwrite( &pe, sizeof( pe ), 1, f ) != 1 ) ||
  215.           ( fwrite( cmd, sizeof( cmd ), 1, f ) != 1 ) ||
  216.           ( fwrite( comp, sizeof( comp ), 1, f ) != 1 ) ||
  217.           ( fwrite( &pe.depends->vcount, sizeof( uint ), 1, f ) != 1 ) ) result = 0;
  218.       for( j = 0; result && ( j < pe.depends->vcount ); j++ )
  219.       {
  220.         pe.depends->gettxt( j, buf );
  221.         if( fwrite( buf, sizeof( buf ), 1, f ) != 1 ) result = 0;
  222.       }
  223.     }
  224.     if( fwrite( &prj_compiler_options, sizeof(prj_compiler_options), 1, f )!=1 ||
  225.         fwrite( &prj_linker_options,   sizeof(prj_linker_options  ), 1, f )!=1 ) result = 0;
  226.     return ( fclose( f ) == 0 ) && result;
  227.   }
  228.  
  229.   void Tproject::new_project_entry( uint i, char *_filename )
  230.   {
  231.     char fname[_MAX_FNAME];
  232.     Tproject_entry pe;
  233.  
  234.     fexpand( strcpy( pe.filename, _filename ) );
  235.     _splitpath( pe.filename, NULL, NULL, fname, NULL );
  236.     min_path( pe.filename );
  237.     strcpy( pe.target, fname );
  238.     strcat( pe.target, ".OBJ" );
  239.     pe.depends = NEW( Tlb_list );
  240.     pe.command_line = STRDUP( "" );
  241.     pe.compiler = STRDUP( "" );
  242.     pe.options = peAUTO_DEPENDENCY;
  243.     ins( i, &pe );
  244.   }
  245.  
  246.   void Tproject::add_entry( void )
  247.   {
  248.     ins_entry( vcount );
  249.   }
  250.  
  251.   void Tproject::ins_entry( uint i )
  252.   {
  253.     char f[_MAX_PATH];
  254.     static char dir_svd[_MAX_PATH] = "";
  255.     static uint filt_svd = 0;
  256.     uint gf;
  257.     _multi_files();
  258.     _get_file_svd( dir_svd, filt_svd );
  259.     _filters( "C++ files (*.cpp)|C files (*.c)|Assembler files (*.asm)" );
  260.     while( gf=get_file("Add/Insert project entry",f) )
  261.     {
  262.       new_project_entry( i++, f );
  263.       if( gf==cmOK ) break;
  264.     }
  265.     save();
  266.   }
  267.  
  268.   void Tproject::edit_file( uint i )
  269.   {
  270.     char filename[_MAX_PATH];
  271.  
  272.     message( this, cmDONE );
  273.     _help( htW_EDITOR );
  274.     strcpy( filename, ( (Tproject_entry *) getptr( i ) )->filename );
  275.     ::edit_file( fexpand( filename ) );
  276.   }
  277.  
  278.   void Tproject::del_entry( uint i )
  279.   {
  280.     _palert();
  281.     if( !yn( "Delete project item?" ) ) return;
  282.     del( i );
  283.     save();
  284.   }
  285.  
  286.     static Tlist_box *dep_list;
  287.     static boolean dependency_validator( uint command )
  288.     {
  289.       char f[_MAX_PATH];
  290.       static char dir_svd[_MAX_PATH] = "";
  291.       static uint filt_svd = 0;
  292.  
  293.       switch( command )
  294.       {
  295.         case cmUSER00:
  296.           _get_file_svd( dir_svd, filt_svd );
  297.           if( get_file( "Add/Insert dependency file", f ) == cmOK )
  298.             dep_list->add( f );
  299.           break;
  300.         case cmUSER01:
  301.           _get_file_svd( dir_svd, filt_svd );
  302.           if( get_file( "Add/Insert dependency file", f ) == cmOK )
  303.             dep_list->ins( dep_list->vcurrent, f );
  304.           break;
  305.         case cmUSER02:
  306.           dep_list->del( dep_list->vcurrent );
  307.           break;
  308.         default:
  309.           return 1;
  310.       }
  311.       cstate( cmUSER02, dep_list->vcount );
  312.       return 0;
  313.     }
  314.  
  315.   void Tproject::dependency( uint i )
  316.   {
  317.     Tproject_entry *pe;
  318.     char buf[_MAX_PATH];
  319.     uint n;
  320.  
  321.     pe = (Tproject_entry *) getptr( i );
  322.     _help( htD_DEPENDENCY );
  323.     dialog( "Dependency list" ); validator( dependency_validator );
  324.     n = 0;
  325.     dep_list = list_box( "|~Dependency files", n, 30, 12 );
  326.       dep_list->set_flags( ifSTAY, 1 );
  327.       for( i = 0; i < pe->depends->vcount; i++ )
  328.       {
  329.         pe->depends->gettxt( i, buf );
  330.         dep_list->add( buf );
  331.       }
  332.       dep_list->top();
  333.     nc();
  334.     hspace();
  335.     kbutton( "  OK  " );
  336.      button( " |~Add  ", cmUSER00 )->cstate( cmUSER02, dep_list->vcount );
  337.      button( "|~Insert", cmUSER01 )->shortcut = kINS;
  338.      button( "|~Delete", cmUSER02 )->shortcut = kDEL;
  339.     cbutton( "Cancel" );
  340.     hbutton( " Help " );
  341.     if( ::run() == cmOK )
  342.     {
  343.       pe->depends->clear();
  344.       for( i = 0; i < dep_list->vcount; i++ )
  345.       {
  346.         dep_list->gettxt( i, buf );
  347.         pe->depends->add( buf );
  348.       }
  349.       save();
  350.     }
  351.     DELETE( dep_list );
  352.   }
  353.  
  354.     static Tinput *export_input;
  355.     static boolean export_validator( uint command )
  356.     {
  357.       if( command==cmOK )
  358.       {
  359.         char path[_MAX_PATH];
  360.         export_input->get_txt( path );
  361.         fexpand( path );
  362.         switch( test_file_exist(path) )
  363.         {
  364.           case cmCANCEL:
  365.             *path = 0;
  366.           case cmYES:
  367.             export_input->set_txt( path );
  368.             return 1;
  369.           case cmNO:
  370.             export_input->set_txt( path );
  371.             focus( export_input );
  372.             return 0;
  373.         }
  374.       }
  375.       return 1;
  376.     }
  377.  
  378.   void Tproject::export( void )
  379.   {
  380.     char fn[_MAX_PATH] = "MAKEFILE";
  381.     _help( htD_EXPORT_MAKEFILE ); dialog( "Export make file" );
  382.     validator( export_validator );
  383.     export_input = input( "File name", fn, _MAX_PATH-1, 20 );
  384.     if( !bkch() || !*fn ) return;
  385.     char *buffer = (char *)MALLOC( MAX_FILE_PARAMS );
  386.     FILE *f=fopen( fn, "wt" );
  387.     fprintf( f, "# Power View IDE makefile export\n\n# Project: %s", filename );
  388.     fprintf( f, "\n\ncode_size = %s", compiler_options.code_size==cs32BITS? "386" : "" );
  389.     watcom_command_line( buffer, "" );
  390.     fprintf( f, "\n\ncompiler_options = %s", buffer );
  391.     watcom_link_command_line( buffer );
  392.     fprintf( f, "\n\nlinker_options =" );
  393.     for( char *c=buffer; *c; c++ )
  394.       if( *c!='\r' )
  395.         fputc( *c, f );
  396.       else
  397.         fputs( " &\n  ", f ), c++;
  398.     fprintf( f, "\n\nobject_files =" );
  399.     for( uint i=0; i<vcount; i++ )
  400.     {
  401.       Tproject_entry *pe = (Tproject_entry *)getptr( i );
  402.       if( pe->options&peDONT_LINK ) continue;
  403.       fprintf( f, " &\n  %s", pe->target );
  404.     }
  405.     exe_file( buffer, filename );
  406.     fprintf( f, "\n\n%s : $(object_files)\n  *wlink $(linker_options) name %s file {$(object_files)}", buffer, buffer );
  407.     for( i=0; i<vcount; i++ )
  408.     {
  409.       Tproject_entry *pe = (Tproject_entry *)getptr( i );
  410.       target_file( buffer, pe->target );
  411.       fprintf( f, "\n\n%s : %s", buffer, pe->filename );
  412.       if( pe->options&peAUTO_DEPENDENCY )
  413.         fprintf( f, " .AUTODEPEND" );
  414.       else
  415.       {
  416.         char buf[_MAX_PATH];
  417.         for( uint j=0; j<pe->depends->vcount; j++ )
  418.         {
  419.           pe->depends->gettxt( j, buf );
  420.           fprintf( f, " %s", buf );
  421.         }
  422.       }
  423.       if( *pe->compiler==0 )
  424.       {
  425.         char ext[_MAX_EXT];
  426.         _splitpath( pe->filename, NULL, NULL, NULL, ext );
  427.         char *wph = (compiler_options.options&opPRECOMPILE)?
  428.           "-fh=$^:$^&.PCH" : "";
  429.         fprintf( f, "\n  %s$(code_size) %s%s%s",
  430.           stricmp(ext,".cpp")==0? "*wpp" : "wcc",
  431.           (pe->options&peEXCLUSIVE)? "" : "$(compiler_options) $[* ",
  432.           (pe->options&peEXCLUSIVE)? "" : wph,
  433.           pe->command_line );
  434.       }
  435.       else
  436.       {
  437.         for( uint j=0; j<ot_tools->vcount; j++ )
  438.         {
  439.           Ttools_entry *te = (Ttools_entry *) ot_tools->getptr( j );
  440.           if( stricmp( pe->compiler, te->title )==0 )
  441.           {
  442.             expand_command_line( te->command_line, pe->filename, buffer );
  443.             fprintf( f, "\n  %s %s", te->path, buffer );
  444.             break;
  445.           }
  446.         }
  447.         if( j>=ot_tools->vcount )
  448.         {
  449.           _terror();
  450.           ok( "Unknown project entry translator: \"%s\".", pe->compiler );
  451.         }
  452.       }
  453.     }
  454.     FREE( buffer );
  455.     if( ferror(f) )
  456.     {
  457.       _terror();
  458.       ok( "Error writting make file %s", fn );
  459.     }
  460.     fclose( f );
  461.   }
  462.  
  463.   void Tproject::local_options( uint i )
  464.   {
  465.     Tproject_entry *pe;
  466.     Ttools_entry *te;
  467.     Tcombo_box *compilers;
  468.     char cmd[128];
  469.     char cm[21];
  470.     char fn[_MAX_FNAME+_MAX_EXT];
  471.     char ext[_MAX_EXT];
  472.     uint j, k, compiler;
  473.  
  474.     _help( htD_LOCAL_OPTIONS );
  475.     dialog( "Local compiler options" );
  476.     pe = (Tproject_entry *) getptr( i );
  477.     _splitpath( pe->filename, NULL, NULL, fn, ext ); strcat( fn, ext );
  478.     _tselected(); _tacenter();
  479.     stext( "Project entry: \"%s\"", 37, fn );
  480.     vspace();
  481.     *cmd = 0;
  482.     strcpy( cmd, pe->command_line );
  483.     _focused();
  484.     compiler = k = 0;
  485.     compilers = combo_box( "|~Compiler    ", compiler, 20 );
  486.       compilers->set_flags( ifSTAY, 1 );
  487.       compilers->add( "Watcom C/C++" );
  488.       for( j = 0; j < ot_tools->vcount; j++ )
  489.       {
  490.         te = (Ttools_entry *) ot_tools->getptr( j );
  491.         if( te->options & teCOMPILER )
  492.         {
  493.           compilers->add( te->title );
  494.           k++;
  495.           if( stricmp( pe->compiler, te->title ) == 0 ) compiler = k;
  496.         }
  497.       }
  498.       compilers->set_data( compiler );
  499.     input( "Command |~line", cmd, 127, 21 );
  500.     vspaces( -1 );
  501.     ::check( "Excl|~usive", pe->options, peEXCLUSIVE );
  502.     vspace();
  503.     input( "|~Target file ", pe->target, _MAX_PATH-1, 21 );
  504.     ::check( "E|~xclude from link",     pe->options, peDONT_LINK       );
  505.     ::check( "|~Auto dependency check", pe->options, peAUTO_DEPENDENCY );
  506.     if( bkch() )
  507.     {
  508.       FREE( pe->command_line );
  509.       FREE( pe->compiler );
  510.       pe->command_line = STRDUP( cmd );
  511.       *cm = 0;
  512.       if( compiler > 0 ) compilers->gettxt( compiler, cm );
  513.       pe->compiler = STRDUP( cm );
  514.       save();
  515.     }
  516.     DELETE( compilers );
  517.   }
  518.  
  519.   boolean Tproject::entry_valid( uint i )
  520.   {
  521.     Tproject_entry *pe;
  522.     char target_filespec[_MAX_PATH];
  523.     char source_filespec[_MAX_PATH];
  524.     uint j;
  525.     boolean result;
  526.  
  527.     pe = (Tproject_entry *) getptr( i );
  528.     if( pe->options & peBUILD ) return 0;
  529.     target_file( target_filespec, pe->target );
  530.     if( pe->options & peAUTO_DEPENDENCY )
  531.     {
  532.       make_status( pe->filename, target_filespec, "Auto dependency check..." );
  533.       result = !need_make( target_filespec );
  534.     }
  535.     else
  536.     {
  537.       make_status( pe->filename, target_filespec, "Dependency check..." );
  538.       result = target_valid( target_filespec, pe->filename );
  539.       for( j = 0; result && ( j < pe->depends->vcount ); j++ )
  540.       {
  541.         pe->depends->gettxt( j, source_filespec );
  542.         result = target_valid( target_filespec, source_filespec );
  543.       }
  544.     }
  545.     return result;
  546.   }
  547.  
  548.   boolean Tproject::exe_valid( boolean general )
  549.   {
  550.     uint i;
  551.     Tproject_entry *pe;
  552.     char exe[_MAX_PATH];
  553.     char target_filespec[_MAX_PATH];
  554.     boolean result;
  555.  
  556.     exe_file( exe, filename );
  557.     result = 1;
  558.     if( general )
  559.       for( i = 0; result && ( i < vcount ); i++ )
  560.         result = entry_valid( i );
  561.     for( i = 0; result && ( i < vcount ); i++ )
  562.     {
  563.       pe = (Tproject_entry *) getptr( i );
  564.       target_file( target_filespec, pe->target );
  565.       result = target_valid( exe, target_filespec );
  566.     }
  567.     return result;
  568.   }
  569.  
  570.   boolean Tproject::build_entry( uint i )
  571.   {
  572.     Tproject_entry *pe;
  573.     Ttools_entry *te;
  574.     char target_filespec[_MAX_PATH];
  575.     char path[_MAX_PATH];
  576.     char buf[_MAX_PATH];
  577.     uint j;
  578.     boolean result;
  579.  
  580.     pe = (Tproject_entry *) getptr( i );
  581.     pe->options &= ~peBUILD;
  582.     target_file( target_filespec, pe->target );
  583.     if( *pe->compiler == 0 )
  584.       result = ( exec_watcom( pe->filename ) == 0 );
  585.     else
  586.     {
  587.       for( j=0; j<ot_tools->vcount; j++ )
  588.       {
  589.         te = (Ttools_entry *) ot_tools->getptr( j );
  590.         if( stricmp( pe->compiler, te->title ) == 0 )
  591.         {
  592.           expand_command_line( te->command_line, pe->filename, path );
  593.           sprintf( buf, "Executing %s...", te->path );
  594.           make_status( pe->filename, target_filespec, buf );
  595.           result = ( ::exec( te->options, te->path, path, te->trap_file ) == 0 );
  596.           break;
  597.         }
  598.       }
  599.       if( j>=ot_tools->vcount )
  600.       {
  601.         result = 0;
  602.         _terror();
  603.         ok( "Unknown project entry translator: \"%s\".", pe->compiler );
  604.       }
  605.     }
  606.     return result && entry_valid( i );
  607.   }
  608.  
  609.   boolean Tproject::make_entry( uint i )
  610.   {
  611.     if( !entry_valid( i ) ) return build_entry( i );
  612.     return 1;
  613.   }
  614.  
  615.   boolean Tproject::make( void )
  616.   {
  617.     uint i;
  618.     boolean fl;
  619.  
  620.     if( memcmp(&prj_compiler_options,&compiler_options,sizeof(Tcompiler_options))!=0 )
  621.     {
  622.       switch( ync( "%s.\n\nDo you wish to rebuild project?",
  623.         FIRST_MAKE?
  624.           "It is first make" :
  625.           "Compiler options has been changed since last make" ) )
  626.       {
  627.         case cmCANCEL:
  628.           return 0;
  629.         case cmYES:
  630.           for( i=0; i<vcount; i++ )
  631.             ((Tproject_entry *)getptr(i))->options |= peBUILD;
  632.       }
  633.       prj_compiler_options = compiler_options;
  634.       save_project();
  635.     }
  636.     broadcast( cmSAVE_ALL );
  637.     fl = 1;
  638.     for( i=0; i<vcount && (fl=make_entry(i)); i++ )
  639.       if( break_make() )
  640.       {
  641.         fl = 0;
  642.         break;
  643.       }
  644.     if( fl ) fl = link( 0 );
  645.     return fl;
  646.   }
  647.  
  648.   boolean Tproject::build( void )
  649.   {
  650.     uint i;
  651.  
  652.     for( i = 0; i < vcount; i++ )
  653.       ( (Tproject_entry *) getptr( i ) )->options |= peBUILD;
  654.     if( memcmp(&prj_compiler_options,&compiler_options,sizeof(Tcompiler_options))!=0 )
  655.     {
  656.       prj_compiler_options = compiler_options;
  657.       save_project();
  658.     }
  659.     return make();
  660.   }
  661.  
  662.   boolean Tproject::link( boolean general )
  663.   {
  664.     boolean fl, link_fl;
  665.  
  666.     fl = 1;
  667.     link_fl = !exe_valid( general );
  668.     if( !link_fl && memcmp(&prj_linker_options,&linker_options,sizeof(Tlinker_options))!=0 )
  669.     {
  670.       switch( ync( "%s.\n\nDo you wish to relink project?",
  671.         FIRST_LINK?
  672.           "It is first link" :
  673.           "Linker options has been changed since last make" ) )
  674.       {
  675.         case cmCANCEL:
  676.           return 0;
  677.         case cmYES:
  678.           link_fl = 1;
  679.       }
  680.       prj_linker_options = linker_options;
  681.       save_project();
  682.     }
  683.     if( link_fl ) fl = ( exec_linker(NULL)==0 );
  684.     return fl;
  685.   }
  686.  
  687.  
  688. /*
  689. protected
  690. */
  691.   void Tproject::event_handler( Tevent &ev )
  692.   {
  693.     Thide_on_close::event_handler( ev );
  694.     if( ev.code==evCOMMAND )
  695.     {
  696.       switch( ev.CMD_CODE )
  697.       {
  698.         case cmPRJ_ADD:
  699.           add_entry();
  700.           break;
  701.         case cmPRJ_INS:
  702.           ins_entry( v_current );
  703.           break;
  704.         case cmPRJ_DEL:
  705.           del_entry( v_current );
  706.           break;
  707.         case cmPRJ_OPTIONS:
  708.           local_options( v_current );
  709.           break;
  710.         case cmPRJ_DEPENDS:
  711.           dependency( v_current );
  712.           break;
  713.         case cmPRJ_EDIT_FILE:
  714.           if( state(isFOCUSED) )
  715.           {
  716.             edit_file( v_current );
  717.             break;
  718.           }
  719.         default:
  720.           return;
  721.       }
  722.       update_commands();
  723.       handled( ev );
  724.     }
  725.   }
  726.  
  727.   void Tproject::update_commands( void )
  728.   {
  729.     cenable( cmPRJ_ADD );
  730.     cstate( cmPRJ_INS,       v_count );
  731.     cstate( cmPRJ_EDIT_FILE, v_count );
  732.     cstate( cmPRJ_DEL,       v_count );
  733.     cstate( cmPRJ_DEPENDS,   v_count );
  734.     cstate( cmPRJ_OPTIONS,   v_count );
  735.   }
  736.  
  737.  
  738. /*
  739. INTERFACE
  740. */
  741.   void open_project( char *filename, boolean show_error )
  742.   {
  743.     Tproject *prj;
  744.     Ttable *tbl;
  745.  
  746.     _help( htW_PROJECT );
  747.     construct_table( "Project", prj = NEW( Tproject( filename, desktop_xl, desktop_yl / 3, show_error ) ) );
  748.               tdata( "Source", 12, _MAX_PATH );
  749.               tdata( "Target",  5, _MAX_PATH );
  750.     _context( cxPROJECT );
  751.     tbl = endt();
  752.     ( (Twindow *) tbl->owner )->palette = wpTOOL;
  753.     local_key( tbl->owner, cmOK, kENTER );
  754.     tbl->owner->set_flags( ifTILEABLE, 0 );
  755.     if( prj->state( isVALID ) )
  756.     {
  757.       project_close();
  758.       project = prj;
  759.     }
  760.     insert_window( tbl->owner, 0, desktop_yl - tbl->owner->yl );
  761.   }
  762.  
  763.   void win_project( void )
  764.   {
  765.     if( project != NULL )
  766.     {
  767.       project->set_state( isHIDDEN, 0 );
  768.       project->owner->owner->set_state( isICONIZED, 0 );
  769.       project->focus();
  770.     }
  771.   }
  772.  
  773.   void project_open( void )
  774.   {
  775.     char f[_MAX_PATH];
  776.     static char dir_svd[_MAX_PATH] = "";
  777.     static uint filt_svd = 0;
  778.     _get_file_svd( dir_svd, filt_svd );
  779.     _filters( "Project files (*.WPJ)" );
  780.     if( get_file( "Open project", f ) == cmOK )
  781.       open_project( f, 0 );
  782.   }
  783.  
  784.   boolean project_build( void )
  785.   //build current file/project
  786.   {
  787.     boolean result;
  788.     start_of_make( "Build" );
  789.     if( project != NULL )
  790.       result = project->build();
  791.     else
  792.       result = project_compile() || link();
  793.     end_of_make( 1 );
  794.     return result;
  795.   }
  796.  
  797.   boolean project_make( void )
  798.   //make current file/project
  799.   {
  800.     boolean result;
  801.     start_of_make( "Make" );
  802.     if( project != NULL )
  803.       result = project->make();
  804.     else
  805.     {
  806.       if( current_editor == NULL ) return 1;
  807.       if( current_editor->booleans & ebMODIFIED )
  808.         message( (Titem *) current_editor->editor, cmSAVE );
  809.       result = ( compile() && link() );
  810.     }
  811.     end_of_make( 1 );
  812.     return result;
  813.   }
  814.  
  815.   void project_run( void )
  816.   //run current file/project
  817.   {
  818.     char buf[_MAX_PATH];
  819.     char *fn;
  820.  
  821.     start_of_make( "Run" );
  822.     if( project_make() )
  823.     {
  824.       if( editor_options.flags & efSAVE_STATUS )
  825.       {
  826.         if( options_changed ) options_save();
  827.         save_status();
  828.       }
  829.       if( project != NULL )
  830.       {
  831.         if( project->exe_valid( 0 ) )
  832.         {
  833.           exe_file( buf, project->filename );
  834.         exec_return:
  835.           end_of_make( 0 );
  836.           exec( 0, buf, program_params, "" );
  837.           return;
  838.         }
  839.       }
  840.       else
  841.         if( current_editor != NULL )
  842.         {
  843.           fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name;
  844.           exe_file( buf, fn );
  845.           if( target_valid( buf, fn ) ) goto exec_return;
  846.         }
  847.     }
  848.     end_of_make( 1 );
  849.   }
  850.  
  851.   void project_params( void )
  852.   //specify current file/project command line
  853.   {
  854.     _help( htD_PARAMS );
  855.     dialog( "Program parameters" );
  856.     _history( program_params );
  857.     input( "|~Parameters", program_params, 125, 25 );
  858.     bkch();
  859.   }
  860.  
  861.   void project_export( void )
  862.   {
  863.     if( project!=NULL ) project->export();
  864.   }
  865.  
  866.   void project_close( void )
  867.   {
  868.     if( project != NULL ) DELETE( project->owner->owner );
  869.     project = NULL;
  870.   }
  871.  
  872.   boolean project_compile( void )
  873.   //compile current file
  874.   {
  875.     char *fn;
  876.     char path[_MAX_PATH];
  877.  
  878.     if( current_editor == NULL ) return 1;
  879.     if( current_editor->booleans & ebMODIFIED )
  880.       message( (Titem *) current_editor->editor, cmSAVE );
  881.     fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name;
  882.     start_of_make( "Compile" );
  883.     if( project!=NULL )
  884.       for( uint i=0; i<project->vcount; i++ )
  885.       {
  886.         Tproject_entry *pe = (Tproject_entry *) project->getptr( i );
  887.         strcpy( path, pe->filename );
  888.         if( strcmp( fexpand( path ), fn )==0 )
  889.         {
  890.           boolean result = project->build_entry( i );
  891.           end_of_make( 1 );
  892.           return result;
  893.         }
  894.       }
  895.     exec_watcom( fn );
  896.     end_of_make( 1 );
  897.     obj_file( path, fn );
  898.     return !need_make( path );
  899.   }
  900.  
  901.   boolean project_link( void )
  902.   //link current file/project
  903.   {
  904.     char path[_MAX_PATH];
  905.     char *fn;
  906.     boolean result;
  907.     start_of_make( "Link" );
  908.     if( project != NULL )
  909.       result = (exec_linker( NULL ) == 0);
  910.     else
  911.     {
  912.       if( current_editor == NULL ) return 1;
  913.       fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name;
  914.       result = (exec_linker( obj_file( path, fn ) ) == 0);
  915.     }
  916.     end_of_make( 1 );
  917.     return result;
  918.   }
  919.